1/* $NetBSD: cert_37.c,v 1.1 2024/02/18 20:57:40 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 23static isc_result_t 24fromtext_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 66static isc_result_t 67totext_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 120static isc_result_t 121fromwire_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 UNUSED(options); 130 131 isc_buffer_activeregion(source, &sr); 132 if (sr.length < 6) { 133 return (ISC_R_UNEXPECTEDEND); 134 } 135 136 isc_buffer_forward(source, sr.length); 137 return (mem_tobuffer(target, sr.base, sr.length)); 138} 139 140static isc_result_t 141towire_cert(ARGS_TOWIRE) { 142 isc_region_t sr; 143 144 REQUIRE(rdata->type == dns_rdatatype_cert); 145 REQUIRE(rdata->length != 0); 146 147 UNUSED(cctx); 148 149 dns_rdata_toregion(rdata, &sr); 150 return (mem_tobuffer(target, sr.base, sr.length)); 151} 152 153static int 154compare_cert(ARGS_COMPARE) { 155 isc_region_t r1; 156 isc_region_t r2; 157 158 REQUIRE(rdata1->type == rdata2->type); 159 REQUIRE(rdata1->rdclass == rdata2->rdclass); 160 REQUIRE(rdata1->type == dns_rdatatype_cert); 161 REQUIRE(rdata1->length != 0); 162 REQUIRE(rdata2->length != 0); 163 164 dns_rdata_toregion(rdata1, &r1); 165 dns_rdata_toregion(rdata2, &r2); 166 return (isc_region_compare(&r1, &r2)); 167} 168 169static isc_result_t 170fromstruct_cert(ARGS_FROMSTRUCT) { 171 dns_rdata_cert_t *cert = source; 172 173 REQUIRE(type == dns_rdatatype_cert); 174 REQUIRE(cert != NULL); 175 REQUIRE(cert->common.rdtype == type); 176 REQUIRE(cert->common.rdclass == rdclass); 177 178 UNUSED(type); 179 UNUSED(rdclass); 180 181 RETERR(uint16_tobuffer(cert->type, target)); 182 RETERR(uint16_tobuffer(cert->key_tag, target)); 183 RETERR(uint8_tobuffer(cert->algorithm, target)); 184 185 return (mem_tobuffer(target, cert->certificate, cert->length)); 186} 187 188static isc_result_t 189tostruct_cert(ARGS_TOSTRUCT) { 190 dns_rdata_cert_t *cert = target; 191 isc_region_t region; 192 193 REQUIRE(rdata->type == dns_rdatatype_cert); 194 REQUIRE(cert != NULL); 195 REQUIRE(rdata->length != 0); 196 197 cert->common.rdclass = rdata->rdclass; 198 cert->common.rdtype = rdata->type; 199 ISC_LINK_INIT(&cert->common, link); 200 201 dns_rdata_toregion(rdata, ®ion); 202 203 cert->type = uint16_fromregion(®ion); 204 isc_region_consume(®ion, 2); 205 cert->key_tag = uint16_fromregion(®ion); 206 isc_region_consume(®ion, 2); 207 cert->algorithm = uint8_fromregion(®ion); 208 isc_region_consume(®ion, 1); 209 cert->length = region.length; 210 211 cert->certificate = mem_maybedup(mctx, region.base, region.length); 212 if (cert->certificate == NULL) { 213 return (ISC_R_NOMEMORY); 214 } 215 216 cert->mctx = mctx; 217 return (ISC_R_SUCCESS); 218} 219 220static void 221freestruct_cert(ARGS_FREESTRUCT) { 222 dns_rdata_cert_t *cert = source; 223 224 REQUIRE(cert != NULL); 225 REQUIRE(cert->common.rdtype == dns_rdatatype_cert); 226 227 if (cert->mctx == NULL) { 228 return; 229 } 230 231 if (cert->certificate != NULL) { 232 isc_mem_free(cert->mctx, cert->certificate); 233 } 234 cert->mctx = NULL; 235} 236 237static isc_result_t 238additionaldata_cert(ARGS_ADDLDATA) { 239 REQUIRE(rdata->type == dns_rdatatype_cert); 240 241 UNUSED(rdata); 242 UNUSED(add); 243 UNUSED(arg); 244 245 return (ISC_R_SUCCESS); 246} 247 248static isc_result_t 249digest_cert(ARGS_DIGEST) { 250 isc_region_t r; 251 252 REQUIRE(rdata->type == dns_rdatatype_cert); 253 254 dns_rdata_toregion(rdata, &r); 255 256 return ((digest)(arg, &r)); 257} 258 259static bool 260checkowner_cert(ARGS_CHECKOWNER) { 261 REQUIRE(type == dns_rdatatype_cert); 262 263 UNUSED(name); 264 UNUSED(type); 265 UNUSED(rdclass); 266 UNUSED(wildcard); 267 268 return (true); 269} 270 271static bool 272checknames_cert(ARGS_CHECKNAMES) { 273 REQUIRE(rdata->type == dns_rdatatype_cert); 274 275 UNUSED(rdata); 276 UNUSED(owner); 277 UNUSED(bad); 278 279 return (true); 280} 281 282static int 283casecompare_cert(ARGS_COMPARE) { 284 return (compare_cert(rdata1, rdata2)); 285} 286#endif /* RDATA_GENERIC_CERT_37_C */ 287