1/* 2 * Copyright (C) 2004, 2005, 2007, 2009, 2011, 2012 Internet Systems Consortium, Inc. ("ISC") 3 * Copyright (C) 1999-2003 Internet Software Consortium. 4 * 5 * Permission to use, copy, modify, and/or distribute this software for any 6 * purpose with or without fee is hereby granted, provided that the above 7 * copyright notice and this permission notice appear in all copies. 8 * 9 * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH 10 * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY 11 * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, 12 * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM 13 * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE 14 * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 15 * PERFORMANCE OF THIS SOFTWARE. 16 */ 17 18/* $Id$ */ 19 20/* Reviewed: Wed Mar 15 21:14:32 EST 2000 by tale */ 21 22/* RFC2538 */ 23 24#ifndef RDATA_GENERIC_CERT_37_C 25#define RDATA_GENERIC_CERT_37_C 26 27#define RRTYPE_CERT_ATTRIBUTES (0) 28 29static inline isc_result_t 30fromtext_cert(ARGS_FROMTEXT) { 31 isc_token_t token; 32 dns_secalg_t secalg; 33 dns_cert_t cert; 34 35 REQUIRE(type == 37); 36 37 UNUSED(type); 38 UNUSED(rdclass); 39 UNUSED(origin); 40 UNUSED(options); 41 UNUSED(callbacks); 42 43 /* 44 * Cert type. 45 */ 46 RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_string, 47 ISC_FALSE)); 48 RETTOK(dns_cert_fromtext(&cert, &token.value.as_textregion)); 49 RETERR(uint16_tobuffer(cert, target)); 50 51 /* 52 * Key tag. 53 */ 54 RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_number, 55 ISC_FALSE)); 56 if (token.value.as_ulong > 0xffffU) 57 RETTOK(ISC_R_RANGE); 58 RETERR(uint16_tobuffer(token.value.as_ulong, target)); 59 60 /* 61 * Algorithm. 62 */ 63 RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_string, 64 ISC_FALSE)); 65 RETTOK(dns_secalg_fromtext(&secalg, &token.value.as_textregion)); 66 RETERR(mem_tobuffer(target, &secalg, 1)); 67 68 return (isc_base64_tobuffer(lexer, target, -1)); 69} 70 71static inline isc_result_t 72totext_cert(ARGS_TOTEXT) { 73 isc_region_t sr; 74 char buf[sizeof("64000 ")]; 75 unsigned int n; 76 77 REQUIRE(rdata->type == 37); 78 REQUIRE(rdata->length != 0); 79 80 UNUSED(tctx); 81 82 dns_rdata_toregion(rdata, &sr); 83 84 /* 85 * Type. 86 */ 87 n = uint16_fromregion(&sr); 88 isc_region_consume(&sr, 2); 89 RETERR(dns_cert_totext((dns_cert_t)n, target)); 90 RETERR(str_totext(" ", target)); 91 92 /* 93 * Key tag. 94 */ 95 n = uint16_fromregion(&sr); 96 isc_region_consume(&sr, 2); 97 sprintf(buf, "%u ", n); 98 RETERR(str_totext(buf, target)); 99 100 /* 101 * Algorithm. 102 */ 103 RETERR(dns_secalg_totext(sr.base[0], target)); 104 isc_region_consume(&sr, 1); 105 106 /* 107 * Cert. 108 */ 109 if ((tctx->flags & DNS_STYLEFLAG_MULTILINE) != 0) 110 RETERR(str_totext(" (", target)); 111 RETERR(str_totext(tctx->linebreak, target)); 112 if (tctx->width == 0) /* No splitting */ 113 RETERR(isc_base64_totext(&sr, 60, "", target)); 114 else 115 RETERR(isc_base64_totext(&sr, tctx->width - 2, 116 tctx->linebreak, target)); 117 if ((tctx->flags & DNS_STYLEFLAG_MULTILINE) != 0) 118 RETERR(str_totext(" )", target)); 119 return (ISC_R_SUCCESS); 120} 121 122static inline isc_result_t 123fromwire_cert(ARGS_FROMWIRE) { 124 isc_region_t sr; 125 126 REQUIRE(type == 37); 127 128 UNUSED(type); 129 UNUSED(rdclass); 130 UNUSED(dctx); 131 UNUSED(options); 132 133 isc_buffer_activeregion(source, &sr); 134 if (sr.length < 5) 135 return (ISC_R_UNEXPECTEDEND); 136 137 isc_buffer_forward(source, sr.length); 138 return (mem_tobuffer(target, sr.base, sr.length)); 139} 140 141static inline isc_result_t 142towire_cert(ARGS_TOWIRE) { 143 isc_region_t sr; 144 145 REQUIRE(rdata->type == 37); 146 REQUIRE(rdata->length != 0); 147 148 UNUSED(cctx); 149 150 dns_rdata_toregion(rdata, &sr); 151 return (mem_tobuffer(target, sr.base, sr.length)); 152} 153 154static inline int 155compare_cert(ARGS_COMPARE) { 156 isc_region_t r1; 157 isc_region_t r2; 158 159 REQUIRE(rdata1->type == rdata2->type); 160 REQUIRE(rdata1->rdclass == rdata2->rdclass); 161 REQUIRE(rdata1->type == 37); 162 REQUIRE(rdata1->length != 0); 163 REQUIRE(rdata2->length != 0); 164 165 dns_rdata_toregion(rdata1, &r1); 166 dns_rdata_toregion(rdata2, &r2); 167 return (isc_region_compare(&r1, &r2)); 168} 169 170static inline isc_result_t 171fromstruct_cert(ARGS_FROMSTRUCT) { 172 dns_rdata_cert_t *cert = source; 173 174 REQUIRE(type == 37); 175 REQUIRE(source != NULL); 176 REQUIRE(cert->common.rdtype == type); 177 REQUIRE(cert->common.rdclass == rdclass); 178 179 UNUSED(type); 180 UNUSED(rdclass); 181 182 RETERR(uint16_tobuffer(cert->type, target)); 183 RETERR(uint16_tobuffer(cert->key_tag, target)); 184 RETERR(uint8_tobuffer(cert->algorithm, target)); 185 186 return (mem_tobuffer(target, cert->certificate, cert->length)); 187} 188 189static inline isc_result_t 190tostruct_cert(ARGS_TOSTRUCT) { 191 dns_rdata_cert_t *cert = target; 192 isc_region_t region; 193 194 REQUIRE(rdata->type == 37); 195 REQUIRE(target != NULL); 196 REQUIRE(rdata->length != 0); 197 198 cert->common.rdclass = rdata->rdclass; 199 cert->common.rdtype = rdata->type; 200 ISC_LINK_INIT(&cert->common, link); 201 202 dns_rdata_toregion(rdata, ®ion); 203 204 cert->type = uint16_fromregion(®ion); 205 isc_region_consume(®ion, 2); 206 cert->key_tag = uint16_fromregion(®ion); 207 isc_region_consume(®ion, 2); 208 cert->algorithm = uint8_fromregion(®ion); 209 isc_region_consume(®ion, 1); 210 cert->length = region.length; 211 212 cert->certificate = mem_maybedup(mctx, region.base, region.length); 213 if (cert->certificate == NULL) 214 return (ISC_R_NOMEMORY); 215 216 cert->mctx = mctx; 217 return (ISC_R_SUCCESS); 218} 219 220static inline void 221freestruct_cert(ARGS_FREESTRUCT) { 222 dns_rdata_cert_t *cert = source; 223 224 REQUIRE(cert != NULL); 225 REQUIRE(cert->common.rdtype == 37); 226 227 if (cert->mctx == NULL) 228 return; 229 230 if (cert->certificate != NULL) 231 isc_mem_free(cert->mctx, cert->certificate); 232 cert->mctx = NULL; 233} 234 235static inline isc_result_t 236additionaldata_cert(ARGS_ADDLDATA) { 237 REQUIRE(rdata->type == 37); 238 239 UNUSED(rdata); 240 UNUSED(add); 241 UNUSED(arg); 242 243 return (ISC_R_SUCCESS); 244} 245 246static inline isc_result_t 247digest_cert(ARGS_DIGEST) { 248 isc_region_t r; 249 250 REQUIRE(rdata->type == 37); 251 252 dns_rdata_toregion(rdata, &r); 253 254 return ((digest)(arg, &r)); 255} 256 257static inline isc_boolean_t 258checkowner_cert(ARGS_CHECKOWNER) { 259 260 REQUIRE(type == 37); 261 262 UNUSED(name); 263 UNUSED(type); 264 UNUSED(rdclass); 265 UNUSED(wildcard); 266 267 return (ISC_TRUE); 268} 269 270static inline isc_boolean_t 271checknames_cert(ARGS_CHECKNAMES) { 272 273 REQUIRE(rdata->type == 37); 274 275 UNUSED(rdata); 276 UNUSED(owner); 277 UNUSED(bad); 278 279 return (ISC_TRUE); 280} 281 282 283static inline int 284casecompare_cert(ARGS_COMPARE) { 285 return (compare_cert(rdata1, rdata2)); 286} 287#endif /* RDATA_GENERIC_CERT_37_C */ 288