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: key_25.c,v 1.13 2020/02/26 18:47:59 florian Exp $ */ 18 19 /* 20 * Reviewed: Wed Mar 15 16:47:10 PST 2000 by halley. 21 */ 22 23 /* RFC2535 */ 24 25 #ifndef RDATA_GENERIC_KEY_25_C 26 #define RDATA_GENERIC_KEY_25_C 27 28 #include <dst/dst.h> 29 30 static inline isc_result_t 31 generic_totext_key(ARGS_TOTEXT) { 32 isc_region_t sr; 33 char buf[sizeof("[key id = 64000]")]; 34 unsigned int flags; 35 unsigned char algorithm; 36 char algbuf[DNS_NAME_FORMATSIZE]; 37 const char *keyinfo; 38 isc_region_t tmpr; 39 40 REQUIRE(rdata->length != 0); 41 42 dns_rdata_toregion(rdata, &sr); 43 44 /* flags */ 45 flags = uint16_fromregion(&sr); 46 isc_region_consume(&sr, 2); 47 snprintf(buf, sizeof(buf), "%u", flags); 48 RETERR(isc_str_tobuffer(buf, target)); 49 RETERR(isc_str_tobuffer(" ", target)); 50 if ((flags & DNS_KEYFLAG_KSK) != 0) { 51 if (flags & DNS_KEYFLAG_REVOKE) 52 keyinfo = "revoked KSK"; 53 else 54 keyinfo = "KSK"; 55 } else 56 keyinfo = "ZSK"; 57 58 /* protocol */ 59 snprintf(buf, sizeof(buf), "%u", sr.base[0]); 60 isc_region_consume(&sr, 1); 61 RETERR(isc_str_tobuffer(buf, target)); 62 RETERR(isc_str_tobuffer(" ", target)); 63 64 /* algorithm */ 65 algorithm = sr.base[0]; 66 snprintf(buf, sizeof(buf), "%u", algorithm); 67 isc_region_consume(&sr, 1); 68 RETERR(isc_str_tobuffer(buf, target)); 69 70 /* No Key? */ 71 if ((flags & 0xc000) == 0xc000) 72 return (ISC_R_SUCCESS); 73 74 if ((tctx->flags & DNS_STYLEFLAG_RRCOMMENT) != 0 && 75 algorithm == DNS_KEYALG_PRIVATEDNS) { 76 dns_name_t name; 77 dns_name_init(&name, NULL); 78 dns_name_fromregion(&name, &sr); 79 dns_name_format(&name, algbuf, sizeof(algbuf)); 80 } else { 81 dns_secalg_format((dns_secalg_t) algorithm, algbuf, 82 sizeof(algbuf)); 83 } 84 85 /* key */ 86 if ((tctx->flags & DNS_STYLEFLAG_MULTILINE) != 0) 87 RETERR(isc_str_tobuffer(" (", target)); 88 RETERR(isc_str_tobuffer(tctx->linebreak, target)); 89 90 if ((tctx->flags & DNS_STYLEFLAG_NOCRYPTO) == 0) { 91 if (tctx->width == 0) /* No splitting */ 92 RETERR(isc_base64_totext(&sr, 60, "", target)); 93 else 94 RETERR(isc_base64_totext(&sr, tctx->width - 2, 95 tctx->linebreak, target)); 96 } else { 97 dns_rdata_toregion(rdata, &tmpr); 98 snprintf(buf, sizeof(buf), "[key id = %u]", 99 dst_region_computeid(&tmpr, algorithm)); 100 RETERR(isc_str_tobuffer(buf, target)); 101 } 102 103 if ((tctx->flags & DNS_STYLEFLAG_RRCOMMENT) != 0) 104 RETERR(isc_str_tobuffer(tctx->linebreak, target)); 105 else if ((tctx->flags & DNS_STYLEFLAG_MULTILINE) != 0) 106 RETERR(isc_str_tobuffer(" ", target)); 107 108 if ((tctx->flags & DNS_STYLEFLAG_MULTILINE) != 0) 109 RETERR(isc_str_tobuffer(")", target)); 110 111 if ((tctx->flags & DNS_STYLEFLAG_RRCOMMENT) != 0) { 112 113 if (rdata->type == dns_rdatatype_dnskey || 114 rdata->type == dns_rdatatype_cdnskey) { 115 RETERR(isc_str_tobuffer(" ; ", target)); 116 RETERR(isc_str_tobuffer(keyinfo, target)); 117 } 118 RETERR(isc_str_tobuffer("; alg = ", target)); 119 RETERR(isc_str_tobuffer(algbuf, target)); 120 RETERR(isc_str_tobuffer(" ; key id = ", target)); 121 dns_rdata_toregion(rdata, &tmpr); 122 snprintf(buf, sizeof(buf), "%u", 123 dst_region_computeid(&tmpr, algorithm)); 124 RETERR(isc_str_tobuffer(buf, target)); 125 } 126 return (ISC_R_SUCCESS); 127 } 128 129 static inline isc_result_t 130 generic_fromwire_key(ARGS_FROMWIRE) { 131 unsigned char algorithm; 132 isc_region_t sr; 133 134 UNUSED(type); 135 UNUSED(rdclass); 136 UNUSED(dctx); 137 UNUSED(options); 138 139 isc_buffer_activeregion(source, &sr); 140 if (sr.length < 4) 141 return (ISC_R_UNEXPECTEDEND); 142 143 algorithm = sr.base[3]; 144 RETERR(isc_mem_tobuffer(target, sr.base, 4)); 145 isc_region_consume(&sr, 4); 146 isc_buffer_forward(source, 4); 147 148 if (algorithm == DNS_KEYALG_PRIVATEDNS) { 149 dns_name_t name; 150 dns_decompress_setmethods(dctx, DNS_COMPRESS_NONE); 151 dns_name_init(&name, NULL); 152 RETERR(dns_name_fromwire(&name, source, dctx, options, target)); 153 } 154 155 /* 156 * RSAMD5 computes key ID differently from other 157 * algorithms: we need to ensure there's enough data 158 * present for the computation 159 */ 160 if (algorithm == DST_ALG_RSAMD5 && sr.length < 3) 161 return (ISC_R_UNEXPECTEDEND); 162 163 isc_buffer_activeregion(source, &sr); 164 isc_buffer_forward(source, sr.length); 165 return (isc_mem_tobuffer(target, sr.base, sr.length)); 166 } 167 168 static inline isc_result_t 169 totext_key(ARGS_TOTEXT) { 170 171 REQUIRE(rdata != NULL); 172 REQUIRE(rdata->type == dns_rdatatype_key); 173 174 return (generic_totext_key(rdata, tctx, target)); 175 } 176 177 static inline isc_result_t 178 fromwire_key(ARGS_FROMWIRE) { 179 180 REQUIRE(type == dns_rdatatype_key); 181 182 return (generic_fromwire_key(rdclass, type, source, dctx, 183 options, target)); 184 } 185 186 static inline isc_result_t 187 towire_key(ARGS_TOWIRE) { 188 isc_region_t sr; 189 190 REQUIRE(rdata != NULL); 191 REQUIRE(rdata->type == dns_rdatatype_key); 192 REQUIRE(rdata->length != 0); 193 194 UNUSED(cctx); 195 196 dns_rdata_toregion(rdata, &sr); 197 return (isc_mem_tobuffer(target, sr.base, sr.length)); 198 } 199 200 #endif /* RDATA_GENERIC_KEY_25_C */ 201