1 /* 2 * Copyright (C) Internet Systems Consortium, Inc. ("ISC") 3 * 4 * Permission to use, copy, modify, and/or distribute this software for any 5 * purpose with or without fee is hereby granted, provided that the above 6 * copyright notice and this permission notice appear in all copies. 7 * 8 * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH 9 * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY 10 * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, 11 * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM 12 * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE 13 * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 14 * PERFORMANCE OF THIS SOFTWARE. 15 */ 16 17 /* $Id: ds_43.c,v 1.13 2020/02/26 18:47:59 florian Exp $ */ 18 19 /* RFC3658 */ 20 21 #ifndef RDATA_GENERIC_DS_43_C 22 #define RDATA_GENERIC_DS_43_C 23 24 #include <isc/sha1.h> 25 #include <isc/sha2.h> 26 27 #include <dns/ds.h> 28 29 static inline isc_result_t 30 generic_totext_ds(ARGS_TOTEXT) { 31 isc_region_t sr; 32 char buf[sizeof("64000 ")]; 33 unsigned int n; 34 35 REQUIRE(rdata->length != 0); 36 37 UNUSED(tctx); 38 39 dns_rdata_toregion(rdata, &sr); 40 41 /* 42 * Key tag. 43 */ 44 n = uint16_fromregion(&sr); 45 isc_region_consume(&sr, 2); 46 snprintf(buf, sizeof(buf), "%u ", n); 47 RETERR(isc_str_tobuffer(buf, target)); 48 49 /* 50 * Algorithm. 51 */ 52 n = uint8_fromregion(&sr); 53 isc_region_consume(&sr, 1); 54 snprintf(buf, sizeof(buf), "%u ", n); 55 RETERR(isc_str_tobuffer(buf, target)); 56 57 /* 58 * Digest type. 59 */ 60 n = uint8_fromregion(&sr); 61 isc_region_consume(&sr, 1); 62 snprintf(buf, sizeof(buf), "%u", n); 63 RETERR(isc_str_tobuffer(buf, target)); 64 65 /* 66 * Digest. 67 */ 68 if ((tctx->flags & DNS_STYLEFLAG_MULTILINE) != 0) 69 RETERR(isc_str_tobuffer(" (", target)); 70 RETERR(isc_str_tobuffer(tctx->linebreak, target)); 71 if ((tctx->flags & DNS_STYLEFLAG_NOCRYPTO) == 0) { 72 if (tctx->width == 0) /* No splitting */ 73 RETERR(isc_hex_totext(&sr, 0, "", target)); 74 else 75 RETERR(isc_hex_totext(&sr, tctx->width - 2, 76 tctx->linebreak, target)); 77 } else 78 RETERR(isc_str_tobuffer("[omitted]", target)); 79 if ((tctx->flags & DNS_STYLEFLAG_MULTILINE) != 0) 80 RETERR(isc_str_tobuffer(" )", target)); 81 return (ISC_R_SUCCESS); 82 } 83 84 static inline isc_result_t 85 totext_ds(ARGS_TOTEXT) { 86 87 REQUIRE(rdata->type == dns_rdatatype_ds); 88 89 return (generic_totext_ds(rdata, tctx, target)); 90 } 91 92 static inline isc_result_t 93 generic_fromwire_ds(ARGS_FROMWIRE) { 94 isc_region_t sr; 95 96 UNUSED(type); 97 UNUSED(rdclass); 98 UNUSED(dctx); 99 UNUSED(options); 100 101 isc_buffer_activeregion(source, &sr); 102 103 /* 104 * Check digest lengths if we know them. 105 */ 106 if (sr.length < 4 || 107 (sr.base[3] == DNS_DSDIGEST_SHA1 && 108 sr.length < 4 + ISC_SHA1_DIGESTLENGTH) || 109 (sr.base[3] == DNS_DSDIGEST_SHA256 && 110 sr.length < 4 + ISC_SHA256_DIGESTLENGTH) || 111 (sr.base[3] == DNS_DSDIGEST_SHA384 && 112 sr.length < 4 + ISC_SHA384_DIGESTLENGTH)) 113 return (ISC_R_UNEXPECTEDEND); 114 115 /* 116 * Only copy digest lengths if we know them. 117 * If there is extra data dns_rdata_fromwire() will 118 * detect that. 119 */ 120 if (sr.base[3] == DNS_DSDIGEST_SHA1) 121 sr.length = 4 + ISC_SHA1_DIGESTLENGTH; 122 else if (sr.base[3] == DNS_DSDIGEST_SHA256) 123 sr.length = 4 + ISC_SHA256_DIGESTLENGTH; 124 else if (sr.base[3] == DNS_DSDIGEST_SHA384) 125 sr.length = 4 + ISC_SHA384_DIGESTLENGTH; 126 127 isc_buffer_forward(source, sr.length); 128 return (isc_mem_tobuffer(target, sr.base, sr.length)); 129 } 130 131 static inline isc_result_t 132 fromwire_ds(ARGS_FROMWIRE) { 133 134 REQUIRE(type == dns_rdatatype_ds); 135 136 return (generic_fromwire_ds(rdclass, type, source, dctx, options, 137 target)); 138 } 139 140 static inline isc_result_t 141 towire_ds(ARGS_TOWIRE) { 142 isc_region_t sr; 143 144 REQUIRE(rdata->type == dns_rdatatype_ds); 145 REQUIRE(rdata->length != 0); 146 147 UNUSED(cctx); 148 149 dns_rdata_toregion(rdata, &sr); 150 return (isc_mem_tobuffer(target, sr.base, sr.length)); 151 } 152 153 #endif /* RDATA_GENERIC_DS_43_C */ 154