1 /* $NetBSD: cert_37.c,v 1.5 2019/11/27 05:48:42 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 http://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 RETERR(uint16_tobuffer(token.value.as_ulong, target)); 51 52 /* 53 * Algorithm. 54 */ 55 RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_string, 56 false)); 57 RETTOK(dns_secalg_fromtext(&secalg, &token.value.as_textregion)); 58 RETERR(mem_tobuffer(target, &secalg, 1)); 59 60 return (isc_base64_tobuffer(lexer, target, -2)); 61 } 62 63 static inline isc_result_t 64 totext_cert(ARGS_TOTEXT) { 65 isc_region_t sr; 66 char buf[sizeof("64000 ")]; 67 unsigned int n; 68 69 REQUIRE(rdata->type == dns_rdatatype_cert); 70 REQUIRE(rdata->length != 0); 71 72 UNUSED(tctx); 73 74 dns_rdata_toregion(rdata, &sr); 75 76 /* 77 * Type. 78 */ 79 n = uint16_fromregion(&sr); 80 isc_region_consume(&sr, 2); 81 RETERR(dns_cert_totext((dns_cert_t)n, target)); 82 RETERR(str_totext(" ", target)); 83 84 /* 85 * Key tag. 86 */ 87 n = uint16_fromregion(&sr); 88 isc_region_consume(&sr, 2); 89 snprintf(buf, sizeof(buf), "%u ", n); 90 RETERR(str_totext(buf, target)); 91 92 /* 93 * Algorithm. 94 */ 95 RETERR(dns_secalg_totext(sr.base[0], target)); 96 isc_region_consume(&sr, 1); 97 98 /* 99 * Cert. 100 */ 101 if ((tctx->flags & DNS_STYLEFLAG_MULTILINE) != 0) 102 RETERR(str_totext(" (", target)); 103 RETERR(str_totext(tctx->linebreak, target)); 104 if (tctx->width == 0) /* No splitting */ 105 RETERR(isc_base64_totext(&sr, 60, "", target)); 106 else 107 RETERR(isc_base64_totext(&sr, tctx->width - 2, 108 tctx->linebreak, target)); 109 if ((tctx->flags & DNS_STYLEFLAG_MULTILINE) != 0) 110 RETERR(str_totext(" )", target)); 111 return (ISC_R_SUCCESS); 112 } 113 114 static inline isc_result_t 115 fromwire_cert(ARGS_FROMWIRE) { 116 isc_region_t sr; 117 118 REQUIRE(type == dns_rdatatype_cert); 119 120 UNUSED(type); 121 UNUSED(rdclass); 122 UNUSED(dctx); 123 UNUSED(options); 124 125 isc_buffer_activeregion(source, &sr); 126 if (sr.length < 5) 127 return (ISC_R_UNEXPECTEDEND); 128 129 isc_buffer_forward(source, sr.length); 130 return (mem_tobuffer(target, sr.base, sr.length)); 131 } 132 133 static inline isc_result_t 134 towire_cert(ARGS_TOWIRE) { 135 isc_region_t sr; 136 137 REQUIRE(rdata->type == dns_rdatatype_cert); 138 REQUIRE(rdata->length != 0); 139 140 UNUSED(cctx); 141 142 dns_rdata_toregion(rdata, &sr); 143 return (mem_tobuffer(target, sr.base, sr.length)); 144 } 145 146 static inline int 147 compare_cert(ARGS_COMPARE) { 148 isc_region_t r1; 149 isc_region_t r2; 150 151 REQUIRE(rdata1->type == rdata2->type); 152 REQUIRE(rdata1->rdclass == rdata2->rdclass); 153 REQUIRE(rdata1->type == dns_rdatatype_cert); 154 REQUIRE(rdata1->length != 0); 155 REQUIRE(rdata2->length != 0); 156 157 dns_rdata_toregion(rdata1, &r1); 158 dns_rdata_toregion(rdata2, &r2); 159 return (isc_region_compare(&r1, &r2)); 160 } 161 162 static inline isc_result_t 163 fromstruct_cert(ARGS_FROMSTRUCT) { 164 dns_rdata_cert_t *cert = source; 165 166 REQUIRE(type == dns_rdatatype_cert); 167 REQUIRE(cert != NULL); 168 REQUIRE(cert->common.rdtype == type); 169 REQUIRE(cert->common.rdclass == rdclass); 170 171 UNUSED(type); 172 UNUSED(rdclass); 173 174 RETERR(uint16_tobuffer(cert->type, target)); 175 RETERR(uint16_tobuffer(cert->key_tag, target)); 176 RETERR(uint8_tobuffer(cert->algorithm, target)); 177 178 return (mem_tobuffer(target, cert->certificate, cert->length)); 179 } 180 181 static inline isc_result_t 182 tostruct_cert(ARGS_TOSTRUCT) { 183 dns_rdata_cert_t *cert = target; 184 isc_region_t region; 185 186 REQUIRE(rdata->type == dns_rdatatype_cert); 187 REQUIRE(cert != NULL); 188 REQUIRE(rdata->length != 0); 189 190 cert->common.rdclass = rdata->rdclass; 191 cert->common.rdtype = rdata->type; 192 ISC_LINK_INIT(&cert->common, link); 193 194 dns_rdata_toregion(rdata, ®ion); 195 196 cert->type = uint16_fromregion(®ion); 197 isc_region_consume(®ion, 2); 198 cert->key_tag = uint16_fromregion(®ion); 199 isc_region_consume(®ion, 2); 200 cert->algorithm = uint8_fromregion(®ion); 201 isc_region_consume(®ion, 1); 202 cert->length = region.length; 203 204 cert->certificate = mem_maybedup(mctx, region.base, region.length); 205 if (cert->certificate == NULL) 206 return (ISC_R_NOMEMORY); 207 208 cert->mctx = mctx; 209 return (ISC_R_SUCCESS); 210 } 211 212 static inline void 213 freestruct_cert(ARGS_FREESTRUCT) { 214 dns_rdata_cert_t *cert = source; 215 216 REQUIRE(cert != NULL); 217 REQUIRE(cert->common.rdtype == dns_rdatatype_cert); 218 219 if (cert->mctx == NULL) 220 return; 221 222 if (cert->certificate != NULL) 223 isc_mem_free(cert->mctx, cert->certificate); 224 cert->mctx = NULL; 225 } 226 227 static inline isc_result_t 228 additionaldata_cert(ARGS_ADDLDATA) { 229 REQUIRE(rdata->type == dns_rdatatype_cert); 230 231 UNUSED(rdata); 232 UNUSED(add); 233 UNUSED(arg); 234 235 return (ISC_R_SUCCESS); 236 } 237 238 static inline isc_result_t 239 digest_cert(ARGS_DIGEST) { 240 isc_region_t r; 241 242 REQUIRE(rdata->type == dns_rdatatype_cert); 243 244 dns_rdata_toregion(rdata, &r); 245 246 return ((digest)(arg, &r)); 247 } 248 249 static inline bool 250 checkowner_cert(ARGS_CHECKOWNER) { 251 252 REQUIRE(type == dns_rdatatype_cert); 253 254 UNUSED(name); 255 UNUSED(type); 256 UNUSED(rdclass); 257 UNUSED(wildcard); 258 259 return (true); 260 } 261 262 static inline bool 263 checknames_cert(ARGS_CHECKNAMES) { 264 265 REQUIRE(rdata->type == dns_rdatatype_cert); 266 267 UNUSED(rdata); 268 UNUSED(owner); 269 UNUSED(bad); 270 271 return (true); 272 } 273 274 275 static inline int 276 casecompare_cert(ARGS_COMPARE) { 277 return (compare_cert(rdata1, rdata2)); 278 } 279 #endif /* RDATA_GENERIC_CERT_37_C */ 280