1 /* $NetBSD: cert_37.c,v 1.10 2025/01/26 16:25:30 christos Exp $ */ 2 3 /* 4 * Copyright (C) Internet Systems Consortium, Inc. ("ISC") 5 * 6 * SPDX-License-Identifier: MPL-2.0 7 * 8 * This Source Code Form is subject to the terms of the Mozilla Public 9 * License, v. 2.0. If a copy of the MPL was not distributed with this 10 * file, you can obtain one at https://mozilla.org/MPL/2.0/. 11 * 12 * See the COPYRIGHT file distributed with this work for additional 13 * information regarding copyright ownership. 14 */ 15 16 /* RFC2538 */ 17 18 #ifndef RDATA_GENERIC_CERT_37_C 19 #define RDATA_GENERIC_CERT_37_C 20 21 #define RRTYPE_CERT_ATTRIBUTES (0) 22 23 static isc_result_t 24 fromtext_cert(ARGS_FROMTEXT) { 25 isc_token_t token; 26 dns_secalg_t secalg; 27 dns_cert_t cert; 28 29 REQUIRE(type == dns_rdatatype_cert); 30 31 UNUSED(type); 32 UNUSED(rdclass); 33 UNUSED(origin); 34 UNUSED(options); 35 UNUSED(callbacks); 36 37 /* 38 * Cert type. 39 */ 40 RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_string, 41 false)); 42 RETTOK(dns_cert_fromtext(&cert, &token.value.as_textregion)); 43 RETERR(uint16_tobuffer(cert, target)); 44 45 /* 46 * Key tag. 47 */ 48 RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_number, 49 false)); 50 if (token.value.as_ulong > 0xffffU) { 51 RETTOK(ISC_R_RANGE); 52 } 53 RETERR(uint16_tobuffer(token.value.as_ulong, target)); 54 55 /* 56 * Algorithm. 57 */ 58 RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_string, 59 false)); 60 RETTOK(dns_secalg_fromtext(&secalg, &token.value.as_textregion)); 61 RETERR(mem_tobuffer(target, &secalg, 1)); 62 63 return isc_base64_tobuffer(lexer, target, -2); 64 } 65 66 static isc_result_t 67 totext_cert(ARGS_TOTEXT) { 68 isc_region_t sr; 69 char buf[sizeof("64000 ")]; 70 unsigned int n; 71 72 REQUIRE(rdata->type == dns_rdatatype_cert); 73 REQUIRE(rdata->length != 0); 74 75 UNUSED(tctx); 76 77 dns_rdata_toregion(rdata, &sr); 78 79 /* 80 * Type. 81 */ 82 n = uint16_fromregion(&sr); 83 isc_region_consume(&sr, 2); 84 RETERR(dns_cert_totext((dns_cert_t)n, target)); 85 RETERR(str_totext(" ", target)); 86 87 /* 88 * Key tag. 89 */ 90 n = uint16_fromregion(&sr); 91 isc_region_consume(&sr, 2); 92 snprintf(buf, sizeof(buf), "%u ", n); 93 RETERR(str_totext(buf, target)); 94 95 /* 96 * Algorithm. 97 */ 98 RETERR(dns_secalg_totext(sr.base[0], target)); 99 isc_region_consume(&sr, 1); 100 101 /* 102 * Cert. 103 */ 104 if ((tctx->flags & DNS_STYLEFLAG_MULTILINE) != 0) { 105 RETERR(str_totext(" (", target)); 106 } 107 RETERR(str_totext(tctx->linebreak, target)); 108 if (tctx->width == 0) { /* No splitting */ 109 RETERR(isc_base64_totext(&sr, 60, "", target)); 110 } else { 111 RETERR(isc_base64_totext(&sr, tctx->width - 2, tctx->linebreak, 112 target)); 113 } 114 if ((tctx->flags & DNS_STYLEFLAG_MULTILINE) != 0) { 115 RETERR(str_totext(" )", target)); 116 } 117 return ISC_R_SUCCESS; 118 } 119 120 static isc_result_t 121 fromwire_cert(ARGS_FROMWIRE) { 122 isc_region_t sr; 123 124 REQUIRE(type == dns_rdatatype_cert); 125 126 UNUSED(type); 127 UNUSED(rdclass); 128 UNUSED(dctx); 129 130 isc_buffer_activeregion(source, &sr); 131 if (sr.length < 6) { 132 return ISC_R_UNEXPECTEDEND; 133 } 134 135 isc_buffer_forward(source, sr.length); 136 return mem_tobuffer(target, sr.base, sr.length); 137 } 138 139 static isc_result_t 140 towire_cert(ARGS_TOWIRE) { 141 isc_region_t sr; 142 143 REQUIRE(rdata->type == dns_rdatatype_cert); 144 REQUIRE(rdata->length != 0); 145 146 UNUSED(cctx); 147 148 dns_rdata_toregion(rdata, &sr); 149 return mem_tobuffer(target, sr.base, sr.length); 150 } 151 152 static int 153 compare_cert(ARGS_COMPARE) { 154 isc_region_t r1; 155 isc_region_t r2; 156 157 REQUIRE(rdata1->type == rdata2->type); 158 REQUIRE(rdata1->rdclass == rdata2->rdclass); 159 REQUIRE(rdata1->type == dns_rdatatype_cert); 160 REQUIRE(rdata1->length != 0); 161 REQUIRE(rdata2->length != 0); 162 163 dns_rdata_toregion(rdata1, &r1); 164 dns_rdata_toregion(rdata2, &r2); 165 return isc_region_compare(&r1, &r2); 166 } 167 168 static isc_result_t 169 fromstruct_cert(ARGS_FROMSTRUCT) { 170 dns_rdata_cert_t *cert = source; 171 172 REQUIRE(type == dns_rdatatype_cert); 173 REQUIRE(cert != NULL); 174 REQUIRE(cert->common.rdtype == type); 175 REQUIRE(cert->common.rdclass == rdclass); 176 177 UNUSED(type); 178 UNUSED(rdclass); 179 180 RETERR(uint16_tobuffer(cert->type, target)); 181 RETERR(uint16_tobuffer(cert->key_tag, target)); 182 RETERR(uint8_tobuffer(cert->algorithm, target)); 183 184 return mem_tobuffer(target, cert->certificate, cert->length); 185 } 186 187 static isc_result_t 188 tostruct_cert(ARGS_TOSTRUCT) { 189 dns_rdata_cert_t *cert = target; 190 isc_region_t region; 191 192 REQUIRE(rdata->type == dns_rdatatype_cert); 193 REQUIRE(cert != NULL); 194 REQUIRE(rdata->length != 0); 195 196 cert->common.rdclass = rdata->rdclass; 197 cert->common.rdtype = rdata->type; 198 ISC_LINK_INIT(&cert->common, link); 199 200 dns_rdata_toregion(rdata, ®ion); 201 202 cert->type = uint16_fromregion(®ion); 203 isc_region_consume(®ion, 2); 204 cert->key_tag = uint16_fromregion(®ion); 205 isc_region_consume(®ion, 2); 206 cert->algorithm = uint8_fromregion(®ion); 207 isc_region_consume(®ion, 1); 208 cert->length = region.length; 209 210 cert->certificate = mem_maybedup(mctx, region.base, region.length); 211 cert->mctx = mctx; 212 return ISC_R_SUCCESS; 213 } 214 215 static void 216 freestruct_cert(ARGS_FREESTRUCT) { 217 dns_rdata_cert_t *cert = source; 218 219 REQUIRE(cert != NULL); 220 REQUIRE(cert->common.rdtype == dns_rdatatype_cert); 221 222 if (cert->mctx == NULL) { 223 return; 224 } 225 226 if (cert->certificate != NULL) { 227 isc_mem_free(cert->mctx, cert->certificate); 228 } 229 cert->mctx = NULL; 230 } 231 232 static isc_result_t 233 additionaldata_cert(ARGS_ADDLDATA) { 234 REQUIRE(rdata->type == dns_rdatatype_cert); 235 236 UNUSED(rdata); 237 UNUSED(owner); 238 UNUSED(add); 239 UNUSED(arg); 240 241 return ISC_R_SUCCESS; 242 } 243 244 static isc_result_t 245 digest_cert(ARGS_DIGEST) { 246 isc_region_t r; 247 248 REQUIRE(rdata->type == dns_rdatatype_cert); 249 250 dns_rdata_toregion(rdata, &r); 251 252 return (digest)(arg, &r); 253 } 254 255 static bool 256 checkowner_cert(ARGS_CHECKOWNER) { 257 REQUIRE(type == dns_rdatatype_cert); 258 259 UNUSED(name); 260 UNUSED(type); 261 UNUSED(rdclass); 262 UNUSED(wildcard); 263 264 return true; 265 } 266 267 static bool 268 checknames_cert(ARGS_CHECKNAMES) { 269 REQUIRE(rdata->type == dns_rdatatype_cert); 270 271 UNUSED(rdata); 272 UNUSED(owner); 273 UNUSED(bad); 274 275 return true; 276 } 277 278 static int 279 casecompare_cert(ARGS_COMPARE) { 280 return compare_cert(rdata1, rdata2); 281 } 282 #endif /* RDATA_GENERIC_CERT_37_C */ 283