rrsig_46.c

Go to the documentation of this file.
00001 /*
00002  * Copyright (C) 2004, 2005, 2007, 2009, 2011-2015  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 /* Reviewed: Fri Mar 17 09:05:02 PST 2000 by gson */
00021 
00022 /* RFC2535 */
00023 
00024 #ifndef RDATA_GENERIC_RRSIG_46_C
00025 #define RDATA_GENERIC_RRSIG_46_C
00026 
00027 #define RRTYPE_RRSIG_ATTRIBUTES (DNS_RDATATYPEATTR_DNSSEC)
00028 
00029 static inline isc_result_t
00030 fromtext_rrsig(ARGS_FROMTEXT) {
00031         isc_token_t token;
00032         unsigned char c;
00033         long i;
00034         dns_rdatatype_t covered;
00035         char *e;
00036         isc_result_t result;
00037         dns_name_t name;
00038         isc_buffer_t buffer;
00039         isc_uint32_t time_signed, time_expire;
00040 
00041         REQUIRE(type == 46);
00042 
00043         UNUSED(type);
00044         UNUSED(rdclass);
00045         UNUSED(callbacks);
00046 
00047         /*
00048          * Type covered.
00049          */
00050         RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_string,
00051                                       ISC_FALSE));
00052         result = dns_rdatatype_fromtext(&covered, &token.value.as_textregion);
00053         if (result != ISC_R_SUCCESS && result != ISC_R_NOTIMPLEMENTED) {
00054                 i = strtol(DNS_AS_STR(token), &e, 10);
00055                 if (i < 0 || i > 65535)
00056                         RETTOK(ISC_R_RANGE);
00057                 if (*e != 0)
00058                         RETTOK(result);
00059                 covered = (dns_rdatatype_t)i;
00060         }
00061         RETERR(uint16_tobuffer(covered, target));
00062 
00063         /*
00064          * Algorithm.
00065          */
00066         RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_string,
00067                                       ISC_FALSE));
00068         RETTOK(dns_secalg_fromtext(&c, &token.value.as_textregion));
00069         RETERR(mem_tobuffer(target, &c, 1));
00070 
00071         /*
00072          * Labels.
00073          */
00074         RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_number,
00075                                       ISC_FALSE));
00076         if (token.value.as_ulong > 0xffU)
00077                 RETTOK(ISC_R_RANGE);
00078         c = (unsigned char)token.value.as_ulong;
00079         RETERR(mem_tobuffer(target, &c, 1));
00080 
00081         /*
00082          * Original ttl.
00083          */
00084         RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_number,
00085                                       ISC_FALSE));
00086         RETERR(uint32_tobuffer(token.value.as_ulong, target));
00087 
00088         /*
00089          * Signature expiration.
00090          */
00091         RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_string,
00092                                       ISC_FALSE));
00093         if (strlen(DNS_AS_STR(token)) <= 10U &&
00094             *DNS_AS_STR(token) != '-' && *DNS_AS_STR(token) != '+') {
00095                 char *end;
00096                 unsigned long u;
00097                 isc_uint64_t u64;
00098 
00099                 u64 = u = strtoul(DNS_AS_STR(token), &end, 10);
00100                 if (u == ULONG_MAX || *end != 0)
00101                         RETTOK(DNS_R_SYNTAX);
00102                 if (u64 > 0xffffffffUL)
00103                         RETTOK(ISC_R_RANGE);
00104                 time_expire = u;
00105         } else
00106                 RETTOK(dns_time32_fromtext(DNS_AS_STR(token), &time_expire));
00107         RETERR(uint32_tobuffer(time_expire, target));
00108 
00109         /*
00110          * Time signed.
00111          */
00112         RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_string,
00113                                       ISC_FALSE));
00114         if (strlen(DNS_AS_STR(token)) <= 10U &&
00115             *DNS_AS_STR(token) != '-' && *DNS_AS_STR(token) != '+') {
00116                 char *end;
00117                 unsigned long u;
00118                 isc_uint64_t u64;
00119 
00120                 u64 = u = strtoul(DNS_AS_STR(token), &end, 10);
00121                 if (u == ULONG_MAX || *end != 0)
00122                         RETTOK(DNS_R_SYNTAX);
00123                 if (u64 > 0xffffffffUL)
00124                         RETTOK(ISC_R_RANGE);
00125                 time_signed = u;
00126         } else
00127                 RETTOK(dns_time32_fromtext(DNS_AS_STR(token), &time_signed));
00128         RETERR(uint32_tobuffer(time_signed, target));
00129 
00130         /*
00131          * Key footprint.
00132          */
00133         RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_number,
00134                                       ISC_FALSE));
00135         RETERR(uint16_tobuffer(token.value.as_ulong, target));
00136 
00137         /*
00138          * Signer.
00139          */
00140         RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_string,
00141                                       ISC_FALSE));
00142         dns_name_init(&name, NULL);
00143         buffer_fromregion(&buffer, &token.value.as_region);
00144         origin = (origin != NULL) ? origin : dns_rootname;
00145         RETTOK(dns_name_fromtext(&name, &buffer, origin, options, target));
00146 
00147         /*
00148          * Sig.
00149          */
00150         return (isc_base64_tobuffer(lexer, target, -1));
00151 }
00152 
00153 static inline isc_result_t
00154 totext_rrsig(ARGS_TOTEXT) {
00155         isc_region_t sr;
00156         char buf[sizeof("4294967295")];
00157         dns_rdatatype_t covered;
00158         unsigned long ttl;
00159         unsigned long when;
00160         unsigned long exp;
00161         unsigned long foot;
00162         dns_name_t name;
00163 
00164         REQUIRE(rdata->type == 46);
00165         REQUIRE(rdata->length != 0);
00166 
00167         dns_rdata_toregion(rdata, &sr);
00168 
00169         /*
00170          * Type covered.
00171          */
00172         covered = uint16_fromregion(&sr);
00173         isc_region_consume(&sr, 2);
00174         /*
00175          * XXXAG We should have something like dns_rdatatype_isknown()
00176          * that does the right thing with type 0.
00177          */
00178         if (dns_rdatatype_isknown(covered) && covered != 0) {
00179                 RETERR(dns_rdatatype_totext(covered, target));
00180         } else {
00181                 sprintf(buf, "TYPE%u", covered);
00182                 RETERR(str_totext(buf, target));
00183         }
00184         RETERR(str_totext(" ", target));
00185 
00186         /*
00187          * Algorithm.
00188          */
00189         sprintf(buf, "%u", sr.base[0]);
00190         isc_region_consume(&sr, 1);
00191         RETERR(str_totext(buf, target));
00192         RETERR(str_totext(" ", target));
00193 
00194         /*
00195          * Labels.
00196          */
00197         sprintf(buf, "%u", sr.base[0]);
00198         isc_region_consume(&sr, 1);
00199         RETERR(str_totext(buf, target));
00200         RETERR(str_totext(" ", target));
00201 
00202         /*
00203          * Ttl.
00204          */
00205         ttl = uint32_fromregion(&sr);
00206         isc_region_consume(&sr, 4);
00207         sprintf(buf, "%lu", ttl);
00208         RETERR(str_totext(buf, target));
00209 
00210         if ((tctx->flags & DNS_STYLEFLAG_MULTILINE) != 0)
00211                 RETERR(str_totext(" (", target));
00212         RETERR(str_totext(tctx->linebreak, target));
00213 
00214         /*
00215          * Sig exp.
00216          */
00217         exp = uint32_fromregion(&sr);
00218         isc_region_consume(&sr, 4);
00219         RETERR(dns_time32_totext(exp, target));
00220         RETERR(str_totext(" ", target));
00221 
00222         /*
00223          * Time signed.
00224          */
00225         when = uint32_fromregion(&sr);
00226         isc_region_consume(&sr, 4);
00227         RETERR(dns_time32_totext(when, target));
00228         RETERR(str_totext(" ", target));
00229 
00230         /*
00231          * Footprint.
00232          */
00233         foot = uint16_fromregion(&sr);
00234         isc_region_consume(&sr, 2);
00235         sprintf(buf, "%lu", foot);
00236         RETERR(str_totext(buf, target));
00237         RETERR(str_totext(" ", target));
00238 
00239         /*
00240          * Signer.
00241          */
00242         dns_name_init(&name, NULL);
00243         dns_name_fromregion(&name, &sr);
00244         isc_region_consume(&sr, name_length(&name));
00245         RETERR(dns_name_totext(&name, ISC_FALSE, target));
00246 
00247         /*
00248          * Sig.
00249          */
00250         RETERR(str_totext(tctx->linebreak, target));
00251         if ((tctx->flags & DNS_STYLEFLAG_NOCRYPTO) == 0) {
00252                 if (tctx->width == 0)   /* No splitting */
00253                         RETERR(isc_base64_totext(&sr, 60, "", target));
00254                 else
00255                         RETERR(isc_base64_totext(&sr, tctx->width - 2,
00256                                                  tctx->linebreak, target));
00257         } else
00258                 RETERR(str_totext("[omitted]", target));
00259 
00260         if ((tctx->flags & DNS_STYLEFLAG_MULTILINE) != 0)
00261                 RETERR(str_totext(" )", target));
00262 
00263         return (ISC_R_SUCCESS);
00264 }
00265 
00266 static inline isc_result_t
00267 fromwire_rrsig(ARGS_FROMWIRE) {
00268         isc_region_t sr;
00269         dns_name_t name;
00270 
00271         REQUIRE(type == 46);
00272 
00273         UNUSED(type);
00274         UNUSED(rdclass);
00275 
00276         dns_decompress_setmethods(dctx, DNS_COMPRESS_NONE);
00277 
00278         isc_buffer_activeregion(source, &sr);
00279         /*
00280          * type covered: 2
00281          * algorithm: 1
00282          * labels: 1
00283          * original ttl: 4
00284          * signature expiration: 4
00285          * time signed: 4
00286          * key footprint: 2
00287          */
00288         if (sr.length < 18)
00289                 return (ISC_R_UNEXPECTEDEND);
00290 
00291         isc_buffer_forward(source, 18);
00292         RETERR(mem_tobuffer(target, sr.base, 18));
00293 
00294         /*
00295          * Signer.
00296          */
00297         dns_name_init(&name, NULL);
00298         RETERR(dns_name_fromwire(&name, source, dctx, options, target));
00299 
00300         /*
00301          * Sig.
00302          */
00303         isc_buffer_activeregion(source, &sr);
00304         isc_buffer_forward(source, sr.length);
00305         return (mem_tobuffer(target, sr.base, sr.length));
00306 }
00307 
00308 static inline isc_result_t
00309 towire_rrsig(ARGS_TOWIRE) {
00310         isc_region_t sr;
00311         dns_name_t name;
00312         dns_offsets_t offsets;
00313 
00314         REQUIRE(rdata->type == 46);
00315         REQUIRE(rdata->length != 0);
00316 
00317         dns_compress_setmethods(cctx, DNS_COMPRESS_NONE);
00318         dns_rdata_toregion(rdata, &sr);
00319         /*
00320          * type covered: 2
00321          * algorithm: 1
00322          * labels: 1
00323          * original ttl: 4
00324          * signature expiration: 4
00325          * time signed: 4
00326          * key footprint: 2
00327          */
00328         RETERR(mem_tobuffer(target, sr.base, 18));
00329         isc_region_consume(&sr, 18);
00330 
00331         /*
00332          * Signer.
00333          */
00334         dns_name_init(&name, offsets);
00335         dns_name_fromregion(&name, &sr);
00336         isc_region_consume(&sr, name_length(&name));
00337         RETERR(dns_name_towire(&name, cctx, target));
00338 
00339         /*
00340          * Signature.
00341          */
00342         return (mem_tobuffer(target, sr.base, sr.length));
00343 }
00344 
00345 static inline int
00346 compare_rrsig(ARGS_COMPARE) {
00347         isc_region_t r1;
00348         isc_region_t r2;
00349 
00350         REQUIRE(rdata1->type == rdata2->type);
00351         REQUIRE(rdata1->rdclass == rdata2->rdclass);
00352         REQUIRE(rdata1->type == 46);
00353         REQUIRE(rdata1->length != 0);
00354         REQUIRE(rdata2->length != 0);
00355 
00356         dns_rdata_toregion(rdata1, &r1);
00357         dns_rdata_toregion(rdata2, &r2);
00358         return (isc_region_compare(&r1, &r2));
00359 }
00360 
00361 static inline isc_result_t
00362 fromstruct_rrsig(ARGS_FROMSTRUCT) {
00363         dns_rdata_rrsig_t *sig = source;
00364 
00365         REQUIRE(type == 46);
00366         REQUIRE(source != NULL);
00367         REQUIRE(sig->common.rdtype == type);
00368         REQUIRE(sig->common.rdclass == rdclass);
00369         REQUIRE(sig->signature != NULL || sig->siglen == 0);
00370 
00371         UNUSED(type);
00372         UNUSED(rdclass);
00373 
00374         /*
00375          * Type covered.
00376          */
00377         RETERR(uint16_tobuffer(sig->covered, target));
00378 
00379         /*
00380          * Algorithm.
00381          */
00382         RETERR(uint8_tobuffer(sig->algorithm, target));
00383 
00384         /*
00385          * Labels.
00386          */
00387         RETERR(uint8_tobuffer(sig->labels, target));
00388 
00389         /*
00390          * Original TTL.
00391          */
00392         RETERR(uint32_tobuffer(sig->originalttl, target));
00393 
00394         /*
00395          * Expire time.
00396          */
00397         RETERR(uint32_tobuffer(sig->timeexpire, target));
00398 
00399         /*
00400          * Time signed.
00401          */
00402         RETERR(uint32_tobuffer(sig->timesigned, target));
00403 
00404         /*
00405          * Key ID.
00406          */
00407         RETERR(uint16_tobuffer(sig->keyid, target));
00408 
00409         /*
00410          * Signer name.
00411          */
00412         RETERR(name_tobuffer(&sig->signer, target));
00413 
00414         /*
00415          * Signature.
00416          */
00417         return (mem_tobuffer(target, sig->signature, sig->siglen));
00418 }
00419 
00420 static inline isc_result_t
00421 tostruct_rrsig(ARGS_TOSTRUCT) {
00422         isc_region_t sr;
00423         dns_rdata_rrsig_t *sig = target;
00424         dns_name_t signer;
00425 
00426         REQUIRE(rdata->type == 46);
00427         REQUIRE(target != NULL);
00428         REQUIRE(rdata->length != 0);
00429 
00430         sig->common.rdclass = rdata->rdclass;
00431         sig->common.rdtype = rdata->type;
00432         ISC_LINK_INIT(&sig->common, link);
00433 
00434         dns_rdata_toregion(rdata, &sr);
00435 
00436         /*
00437          * Type covered.
00438          */
00439         sig->covered = uint16_fromregion(&sr);
00440         isc_region_consume(&sr, 2);
00441 
00442         /*
00443          * Algorithm.
00444          */
00445         sig->algorithm = uint8_fromregion(&sr);
00446         isc_region_consume(&sr, 1);
00447 
00448         /*
00449          * Labels.
00450          */
00451         sig->labels = uint8_fromregion(&sr);
00452         isc_region_consume(&sr, 1);
00453 
00454         /*
00455          * Original TTL.
00456          */
00457         sig->originalttl = uint32_fromregion(&sr);
00458         isc_region_consume(&sr, 4);
00459 
00460         /*
00461          * Expire time.
00462          */
00463         sig->timeexpire = uint32_fromregion(&sr);
00464         isc_region_consume(&sr, 4);
00465 
00466         /*
00467          * Time signed.
00468          */
00469         sig->timesigned = uint32_fromregion(&sr);
00470         isc_region_consume(&sr, 4);
00471 
00472         /*
00473          * Key ID.
00474          */
00475         sig->keyid = uint16_fromregion(&sr);
00476         isc_region_consume(&sr, 2);
00477 
00478         dns_name_init(&signer, NULL);
00479         dns_name_fromregion(&signer, &sr);
00480         dns_name_init(&sig->signer, NULL);
00481         RETERR(name_duporclone(&signer, mctx, &sig->signer));
00482         isc_region_consume(&sr, name_length(&sig->signer));
00483 
00484         /*
00485          * Signature.
00486          */
00487         sig->siglen = sr.length;
00488         sig->signature = mem_maybedup(mctx, sr.base, sig->siglen);
00489         if (sig->signature == NULL)
00490                 goto cleanup;
00491 
00492 
00493         sig->mctx = mctx;
00494         return (ISC_R_SUCCESS);
00495 
00496  cleanup:
00497         if (mctx != NULL)
00498                 dns_name_free(&sig->signer, mctx);
00499         return (ISC_R_NOMEMORY);
00500 }
00501 
00502 static inline void
00503 freestruct_rrsig(ARGS_FREESTRUCT) {
00504         dns_rdata_rrsig_t *sig = (dns_rdata_rrsig_t *) source;
00505 
00506         REQUIRE(source != NULL);
00507         REQUIRE(sig->common.rdtype == 46);
00508 
00509         if (sig->mctx == NULL)
00510                 return;
00511 
00512         dns_name_free(&sig->signer, sig->mctx);
00513         if (sig->signature != NULL)
00514                 isc_mem_free(sig->mctx, sig->signature);
00515         sig->mctx = NULL;
00516 }
00517 
00518 static inline isc_result_t
00519 additionaldata_rrsig(ARGS_ADDLDATA) {
00520         REQUIRE(rdata->type == 46);
00521 
00522         UNUSED(rdata);
00523         UNUSED(add);
00524         UNUSED(arg);
00525 
00526         return (ISC_R_SUCCESS);
00527 }
00528 
00529 static inline isc_result_t
00530 digest_rrsig(ARGS_DIGEST) {
00531 
00532         REQUIRE(rdata->type == 46);
00533 
00534         UNUSED(rdata);
00535         UNUSED(digest);
00536         UNUSED(arg);
00537 
00538         return (ISC_R_NOTIMPLEMENTED);
00539 }
00540 
00541 static inline dns_rdatatype_t
00542 covers_rrsig(dns_rdata_t *rdata) {
00543         dns_rdatatype_t type;
00544         isc_region_t r;
00545 
00546         REQUIRE(rdata->type == 46);
00547 
00548         dns_rdata_toregion(rdata, &r);
00549         type = uint16_fromregion(&r);
00550 
00551         return (type);
00552 }
00553 
00554 static inline isc_boolean_t
00555 checkowner_rrsig(ARGS_CHECKOWNER) {
00556 
00557         REQUIRE(type == 46);
00558 
00559         UNUSED(name);
00560         UNUSED(type);
00561         UNUSED(rdclass);
00562         UNUSED(wildcard);
00563 
00564         return (ISC_TRUE);
00565 }
00566 
00567 static inline isc_boolean_t
00568 checknames_rrsig(ARGS_CHECKNAMES) {
00569 
00570         REQUIRE(rdata->type == 46);
00571 
00572         UNUSED(rdata);
00573         UNUSED(owner);
00574         UNUSED(bad);
00575 
00576         return (ISC_TRUE);
00577 }
00578 
00579 static inline int
00580 casecompare_rrsig(ARGS_COMPARE) {
00581         isc_region_t r1;
00582         isc_region_t r2;
00583         dns_name_t name1;
00584         dns_name_t name2;
00585         int order;
00586 
00587         REQUIRE(rdata1->type == rdata2->type);
00588         REQUIRE(rdata1->rdclass == rdata2->rdclass);
00589         REQUIRE(rdata1->type == 46);
00590         REQUIRE(rdata1->length != 0);
00591         REQUIRE(rdata2->length != 0);
00592 
00593         dns_rdata_toregion(rdata1, &r1);
00594         dns_rdata_toregion(rdata2, &r2);
00595 
00596         INSIST(r1.length > 18);
00597         INSIST(r2.length > 18);
00598         r1.length = 18;
00599         r2.length = 18;
00600         order = isc_region_compare(&r1, &r2);
00601         if (order != 0)
00602                 return (order);
00603 
00604         dns_name_init(&name1, NULL);
00605         dns_name_init(&name2, NULL);
00606         dns_rdata_toregion(rdata1, &r1);
00607         dns_rdata_toregion(rdata2, &r2);
00608         isc_region_consume(&r1, 18);
00609         isc_region_consume(&r2, 18);
00610         dns_name_fromregion(&name1, &r1);
00611         dns_name_fromregion(&name2, &r2);
00612         order = dns_name_rdatacompare(&name1, &name2);
00613         if (order != 0)
00614                 return (order);
00615 
00616         isc_region_consume(&r1, name_length(&name1));
00617         isc_region_consume(&r2, name_length(&name2));
00618 
00619         return (isc_region_compare(&r1, &r2));
00620 }
00621 
00622 #endif  /* RDATA_GENERIC_RRSIG_46_C */

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