cdnskey_60.c

Go to the documentation of this file.
00001 /*
00002  * Copyright (C) 2014, 2015  Internet Systems Consortium, Inc. ("ISC")
00003  *
00004  * Permission to use, copy, modify, and/or distribute this software for any
00005  * purpose with or without fee is hereby granted, provided that the above
00006  * copyright notice and this permission notice appear in all copies.
00007  *
00008  * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
00009  * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
00010  * AND FITNESS.  IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
00011  * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
00012  * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
00013  * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
00014  * PERFORMANCE OF THIS SOFTWARE.
00015  */
00016 
00017 /* draft-ietf-dnsop-delegation-trust-maintainance-14 */
00018 
00019 #ifndef RDATA_GENERIC_CDNSKEY_60_C
00020 #define RDATA_GENERIC_CDNSKEY_60_C
00021 
00022 #include <dst/dst.h>
00023 
00024 #define RRTYPE_CDNSKEY_ATTRIBUTES 0
00025 
00026 static inline isc_result_t
00027 fromtext_cdnskey(ARGS_FROMTEXT) {
00028         isc_result_t result;
00029         isc_token_t token;
00030         dns_secalg_t alg;
00031         dns_secproto_t proto;
00032         dns_keyflags_t flags;
00033 
00034         REQUIRE(type == 60);
00035 
00036         UNUSED(type);
00037         UNUSED(rdclass);
00038         UNUSED(origin);
00039         UNUSED(options);
00040         UNUSED(callbacks);
00041 
00042         /* flags */
00043         RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_string,
00044                                       ISC_FALSE));
00045         RETTOK(dns_keyflags_fromtext(&flags, &token.value.as_textregion));
00046         RETERR(uint16_tobuffer(flags, target));
00047 
00048         /* protocol */
00049         RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_string,
00050                                       ISC_FALSE));
00051         RETTOK(dns_secproto_fromtext(&proto, &token.value.as_textregion));
00052         RETERR(mem_tobuffer(target, &proto, 1));
00053 
00054         /* algorithm */
00055         RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_string,
00056                                       ISC_FALSE));
00057         RETTOK(dns_secalg_fromtext(&alg, &token.value.as_textregion));
00058         RETERR(mem_tobuffer(target, &alg, 1));
00059 
00060         /* No Key? */
00061         if ((flags & 0xc000) == 0xc000)
00062                 return (ISC_R_SUCCESS);
00063 
00064         result = isc_base64_tobuffer(lexer, target, -1);
00065         if (result != ISC_R_SUCCESS)
00066                 return (result);
00067 
00068         /* Ensure there's at least enough data to compute a key ID for MD5 */
00069         if (alg == DST_ALG_RSAMD5 && isc_buffer_usedlength(target) < 7)
00070                 return (ISC_R_UNEXPECTEDEND);
00071 
00072         return (ISC_R_SUCCESS);
00073 }
00074 
00075 static inline isc_result_t
00076 totext_cdnskey(ARGS_TOTEXT) {
00077         isc_region_t sr;
00078         char buf[sizeof("[key id = 64000]")];
00079         unsigned int flags;
00080         unsigned char algorithm;
00081         char algbuf[DNS_NAME_FORMATSIZE];
00082         const char *keyinfo;
00083         isc_region_t tmpr;
00084 
00085         REQUIRE(rdata->type == 60);
00086         REQUIRE(rdata->length != 0);
00087 
00088         dns_rdata_toregion(rdata, &sr);
00089 
00090         /* flags */
00091         flags = uint16_fromregion(&sr);
00092         isc_region_consume(&sr, 2);
00093         sprintf(buf, "%u", flags);
00094         RETERR(str_totext(buf, target));
00095         RETERR(str_totext(" ", target));
00096         if ((flags & DNS_KEYFLAG_KSK) != 0) {
00097                 if (flags & DNS_KEYFLAG_REVOKE)
00098                         keyinfo = "revoked KSK";
00099                 else
00100                         keyinfo = "KSK";
00101         } else
00102                 keyinfo = "ZSK";
00103 
00104         /* protocol */
00105         sprintf(buf, "%u", sr.base[0]);
00106         isc_region_consume(&sr, 1);
00107         RETERR(str_totext(buf, target));
00108         RETERR(str_totext(" ", target));
00109 
00110         /* algorithm */
00111         algorithm = sr.base[0];
00112         sprintf(buf, "%u", algorithm);
00113         isc_region_consume(&sr, 1);
00114         RETERR(str_totext(buf, target));
00115 
00116         /* No Key? */
00117         if ((flags & 0xc000) == 0xc000)
00118                 return (ISC_R_SUCCESS);
00119 
00120         if ((tctx->flags & DNS_STYLEFLAG_RRCOMMENT) != 0 &&
00121              algorithm == DNS_KEYALG_PRIVATEDNS) {
00122                 dns_name_t name;
00123                 dns_name_init(&name, NULL);
00124                 dns_name_fromregion(&name, &sr);
00125                 dns_name_format(&name, algbuf, sizeof(algbuf));
00126         } else {
00127                 dns_secalg_format((dns_secalg_t) algorithm, algbuf,
00128                                   sizeof(algbuf));
00129         }
00130 
00131         /* key */
00132         if ((tctx->flags & DNS_STYLEFLAG_MULTILINE) != 0)
00133                 RETERR(str_totext(" (", target));
00134         RETERR(str_totext(tctx->linebreak, target));
00135 
00136         if ((tctx->flags & DNS_STYLEFLAG_NOCRYPTO) == 0) {
00137                 if (tctx->width == 0)   /* No splitting */
00138                         RETERR(isc_base64_totext(&sr, 0, "", target));
00139                 else
00140                         RETERR(isc_base64_totext(&sr, tctx->width - 2,
00141                                                  tctx->linebreak, target));
00142         } else {
00143                 dns_rdata_toregion(rdata, &tmpr);
00144                 snprintf(buf, sizeof(buf), "[key id = %u]",
00145                          dst_region_computeid(&tmpr, algorithm));
00146                 RETERR(str_totext(buf, target));
00147         }
00148 
00149         if ((tctx->flags & DNS_STYLEFLAG_RRCOMMENT) != 0)
00150                 RETERR(str_totext(tctx->linebreak, target));
00151         else if ((tctx->flags & DNS_STYLEFLAG_MULTILINE) != 0)
00152                 RETERR(str_totext(" ", target));
00153 
00154         if ((tctx->flags & DNS_STYLEFLAG_MULTILINE) != 0)
00155                 RETERR(str_totext(")", target));
00156 
00157         if ((tctx->flags & DNS_STYLEFLAG_RRCOMMENT) != 0) {
00158 
00159                 RETERR(str_totext(" ; ", target));
00160                 RETERR(str_totext(keyinfo, target));
00161                 RETERR(str_totext("; alg = ", target));
00162                 RETERR(str_totext(algbuf, target));
00163                 RETERR(str_totext("; key id = ", target));
00164                 dns_rdata_toregion(rdata, &tmpr);
00165                 sprintf(buf, "%u", dst_region_computeid(&tmpr, algorithm));
00166                 RETERR(str_totext(buf, target));
00167         }
00168         return (ISC_R_SUCCESS);
00169 }
00170 
00171 static inline isc_result_t
00172 fromwire_cdnskey(ARGS_FROMWIRE) {
00173         unsigned char algorithm;
00174         isc_region_t sr;
00175 
00176         REQUIRE(type == 60);
00177 
00178         UNUSED(type);
00179         UNUSED(rdclass);
00180         UNUSED(dctx);
00181         UNUSED(options);
00182 
00183         isc_buffer_activeregion(source, &sr);
00184         if (sr.length < 4)
00185                 return (ISC_R_UNEXPECTEDEND);
00186 
00187         algorithm = sr.base[3];
00188         RETERR(mem_tobuffer(target, sr.base, 4));
00189         isc_region_consume(&sr, 4);
00190         isc_buffer_forward(source, 4);
00191 
00192         if (algorithm == DNS_KEYALG_PRIVATEDNS) {
00193                 dns_name_t name;
00194                 dns_decompress_setmethods(dctx, DNS_COMPRESS_NONE);
00195                 dns_name_init(&name, NULL);
00196                 RETERR(dns_name_fromwire(&name, source, dctx, options, target));
00197         }
00198 
00199         /*
00200          * RSAMD5 computes key ID differently from other
00201          * algorithms: we need to ensure there's enough data
00202          * present for the computation
00203          */
00204         if (algorithm == DST_ALG_RSAMD5 && sr.length < 3)
00205                 return (ISC_R_UNEXPECTEDEND);
00206 
00207         isc_buffer_activeregion(source, &sr);
00208         isc_buffer_forward(source, sr.length);
00209         return (mem_tobuffer(target, sr.base, sr.length));
00210 }
00211 
00212 static inline isc_result_t
00213 towire_cdnskey(ARGS_TOWIRE) {
00214         isc_region_t sr;
00215 
00216         REQUIRE(rdata->type == 60);
00217         REQUIRE(rdata->length != 0);
00218 
00219         UNUSED(cctx);
00220 
00221         dns_rdata_toregion(rdata, &sr);
00222         return (mem_tobuffer(target, sr.base, sr.length));
00223 }
00224 
00225 static inline int
00226 compare_cdnskey(ARGS_COMPARE) {
00227         isc_region_t r1;
00228         isc_region_t r2;
00229 
00230         REQUIRE(rdata1->type == rdata2->type);
00231         REQUIRE(rdata1->rdclass == rdata2->rdclass);
00232         REQUIRE(rdata1->type == 60);
00233         REQUIRE(rdata1->length != 0);
00234         REQUIRE(rdata2->length != 0);
00235 
00236         dns_rdata_toregion(rdata1, &r1);
00237         dns_rdata_toregion(rdata2, &r2);
00238         return (isc_region_compare(&r1, &r2));
00239 }
00240 
00241 static inline isc_result_t
00242 fromstruct_cdnskey(ARGS_FROMSTRUCT) {
00243         dns_rdata_cdnskey_t *dnskey = source;
00244 
00245         REQUIRE(type == 60);
00246         REQUIRE(source != NULL);
00247         REQUIRE(dnskey->common.rdtype == type);
00248         REQUIRE(dnskey->common.rdclass == rdclass);
00249 
00250         UNUSED(type);
00251         UNUSED(rdclass);
00252 
00253         /* Flags */
00254         RETERR(uint16_tobuffer(dnskey->flags, target));
00255 
00256         /* Protocol */
00257         RETERR(uint8_tobuffer(dnskey->protocol, target));
00258 
00259         /* Algorithm */
00260         RETERR(uint8_tobuffer(dnskey->algorithm, target));
00261 
00262         /* Data */
00263         return (mem_tobuffer(target, dnskey->data, dnskey->datalen));
00264 }
00265 
00266 static inline isc_result_t
00267 tostruct_cdnskey(ARGS_TOSTRUCT) {
00268         dns_rdata_cdnskey_t *dnskey = target;
00269         isc_region_t sr;
00270 
00271         REQUIRE(rdata->type == 60);
00272         REQUIRE(target != NULL);
00273         REQUIRE(rdata->length != 0);
00274 
00275         dnskey->common.rdclass = rdata->rdclass;
00276         dnskey->common.rdtype = rdata->type;
00277         ISC_LINK_INIT(&dnskey->common, link);
00278 
00279         dns_rdata_toregion(rdata, &sr);
00280 
00281         /* Flags */
00282         if (sr.length < 2)
00283                 return (ISC_R_UNEXPECTEDEND);
00284         dnskey->flags = uint16_fromregion(&sr);
00285         isc_region_consume(&sr, 2);
00286 
00287         /* Protocol */
00288         if (sr.length < 1)
00289                 return (ISC_R_UNEXPECTEDEND);
00290         dnskey->protocol = uint8_fromregion(&sr);
00291         isc_region_consume(&sr, 1);
00292 
00293         /* Algorithm */
00294         if (sr.length < 1)
00295                 return (ISC_R_UNEXPECTEDEND);
00296         dnskey->algorithm = uint8_fromregion(&sr);
00297         isc_region_consume(&sr, 1);
00298 
00299         /* Data */
00300         dnskey->datalen = sr.length;
00301         dnskey->data = mem_maybedup(mctx, sr.base, dnskey->datalen);
00302         if (dnskey->data == NULL)
00303                 return (ISC_R_NOMEMORY);
00304 
00305         dnskey->mctx = mctx;
00306         return (ISC_R_SUCCESS);
00307 }
00308 
00309 static inline void
00310 freestruct_cdnskey(ARGS_FREESTRUCT) {
00311         dns_rdata_cdnskey_t *dnskey = (dns_rdata_cdnskey_t *) source;
00312 
00313         REQUIRE(source != NULL);
00314         REQUIRE(dnskey->common.rdtype == 60);
00315 
00316         if (dnskey->mctx == NULL)
00317                 return;
00318 
00319         if (dnskey->data != NULL)
00320                 isc_mem_free(dnskey->mctx, dnskey->data);
00321         dnskey->mctx = NULL;
00322 }
00323 
00324 static inline isc_result_t
00325 additionaldata_cdnskey(ARGS_ADDLDATA) {
00326         REQUIRE(rdata->type == 60);
00327 
00328         UNUSED(rdata);
00329         UNUSED(add);
00330         UNUSED(arg);
00331 
00332         return (ISC_R_SUCCESS);
00333 }
00334 
00335 static inline isc_result_t
00336 digest_cdnskey(ARGS_DIGEST) {
00337         isc_region_t r;
00338 
00339         REQUIRE(rdata->type == 60);
00340 
00341         dns_rdata_toregion(rdata, &r);
00342 
00343         return ((digest)(arg, &r));
00344 }
00345 
00346 static inline isc_boolean_t
00347 checkowner_cdnskey(ARGS_CHECKOWNER) {
00348 
00349         REQUIRE(type == 60);
00350 
00351         UNUSED(name);
00352         UNUSED(type);
00353         UNUSED(rdclass);
00354         UNUSED(wildcard);
00355 
00356         return (ISC_TRUE);
00357 }
00358 
00359 static inline isc_boolean_t
00360 checknames_cdnskey(ARGS_CHECKNAMES) {
00361 
00362         REQUIRE(rdata->type == 60);
00363 
00364         UNUSED(rdata);
00365         UNUSED(owner);
00366         UNUSED(bad);
00367 
00368         return (ISC_TRUE);
00369 }
00370 
00371 static inline int
00372 casecompare_cdnskey(ARGS_COMPARE) {
00373 
00374         /*
00375          * Treat ALG 253 (private DNS) subtype name case sensistively.
00376          */
00377         return (compare_cdnskey(rdata1, rdata2));
00378 }
00379 
00380 #endif  /* RDATA_GENERIC_CDNSKEY_60_C */

Generated on Tue Apr 28 17:40:59 2015 by Doxygen 1.5.4 for BIND9 Internals 9.11.0pre-alpha