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