dnskey_48.c

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

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