2 * Copyright (C) 2014, 2015 Internet Systems Consortium, Inc. ("ISC")
4 * Permission to use, copy, modify, and/or distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies.
8 * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
9 * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
10 * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
11 * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
12 * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
13 * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
14 * PERFORMANCE OF THIS SOFTWARE.
19 /* draft-ietf-dnsext-delegation-signer-05.txt */
21 #ifndef RDATA_GENERIC_CDS_59_C
22 #define RDATA_GENERIC_CDS_59_C
24 #define RRTYPE_CDS_ATTRIBUTES 0
31 static inline isc_result_t
32 fromtext_cds(ARGS_FROMTEXT) {
37 REQUIRE(type == dns_rdatatype_cds);
48 RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_number,
50 if (token.value.as_ulong > 0xffffU)
52 RETERR(uint16_tobuffer(token.value.as_ulong, target));
57 RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_string,
59 RETTOK(dns_secalg_fromtext(&c, &token.value.as_textregion));
60 RETERR(mem_tobuffer(target, &c, 1));
65 RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_number,
67 if (token.value.as_ulong > 0xffU)
69 RETERR(uint8_tobuffer(token.value.as_ulong, target));
70 c = (unsigned char) token.value.as_ulong;
76 case DNS_DSDIGEST_SHA1:
77 length = ISC_SHA1_DIGESTLENGTH;
79 case DNS_DSDIGEST_SHA256:
80 length = ISC_SHA256_DIGESTLENGTH;
82 case DNS_DSDIGEST_GOST:
83 length = ISC_GOST_DIGESTLENGTH;
85 case DNS_DSDIGEST_SHA384:
86 length = ISC_SHA384_DIGESTLENGTH;
92 return (isc_hex_tobuffer(lexer, target, length));
95 static inline isc_result_t
96 totext_cds(ARGS_TOTEXT) {
98 char buf[sizeof("64000 ")];
101 REQUIRE(rdata->type == dns_rdatatype_cds);
102 REQUIRE(rdata->length != 0);
106 dns_rdata_toregion(rdata, &sr);
111 n = uint16_fromregion(&sr);
112 isc_region_consume(&sr, 2);
113 sprintf(buf, "%u ", n);
114 RETERR(str_totext(buf, target));
119 n = uint8_fromregion(&sr);
120 isc_region_consume(&sr, 1);
121 sprintf(buf, "%u ", n);
122 RETERR(str_totext(buf, target));
127 n = uint8_fromregion(&sr);
128 isc_region_consume(&sr, 1);
129 sprintf(buf, "%u", n);
130 RETERR(str_totext(buf, target));
135 if ((tctx->flags & DNS_STYLEFLAG_MULTILINE) != 0)
136 RETERR(str_totext(" (", target));
137 RETERR(str_totext(tctx->linebreak, target));
138 if (tctx->width == 0) /* No splitting */
139 RETERR(isc_hex_totext(&sr, 0, "", target));
141 RETERR(isc_hex_totext(&sr, tctx->width - 2,
142 tctx->linebreak, target));
143 if ((tctx->flags & DNS_STYLEFLAG_MULTILINE) != 0)
144 RETERR(str_totext(" )", target));
145 return (ISC_R_SUCCESS);
148 static inline isc_result_t
149 fromwire_cds(ARGS_FROMWIRE) {
152 REQUIRE(type == dns_rdatatype_cds);
159 isc_buffer_activeregion(source, &sr);
162 * Check digest lengths if we know them.
165 (sr.base[3] == DNS_DSDIGEST_SHA1 &&
166 sr.length < 4 + ISC_SHA1_DIGESTLENGTH) ||
167 (sr.base[3] == DNS_DSDIGEST_SHA256 &&
168 sr.length < 4 + ISC_SHA256_DIGESTLENGTH) ||
169 (sr.base[3] == DNS_DSDIGEST_GOST &&
170 sr.length < 4 + ISC_GOST_DIGESTLENGTH) ||
171 (sr.base[3] == DNS_DSDIGEST_SHA384 &&
172 sr.length < 4 + ISC_SHA384_DIGESTLENGTH))
173 return (ISC_R_UNEXPECTEDEND);
176 * Only copy digest lengths if we know them.
177 * If there is extra data dns_rdata_fromwire() will
180 if (sr.base[3] == DNS_DSDIGEST_SHA1)
181 sr.length = 4 + ISC_SHA1_DIGESTLENGTH;
182 else if (sr.base[3] == DNS_DSDIGEST_SHA256)
183 sr.length = 4 + ISC_SHA256_DIGESTLENGTH;
184 else if (sr.base[3] == DNS_DSDIGEST_GOST)
185 sr.length = 4 + ISC_GOST_DIGESTLENGTH;
186 else if (sr.base[3] == DNS_DSDIGEST_SHA384)
187 sr.length = 4 + ISC_SHA384_DIGESTLENGTH;
189 isc_buffer_forward(source, sr.length);
190 return (mem_tobuffer(target, sr.base, sr.length));
193 static inline isc_result_t
194 towire_cds(ARGS_TOWIRE) {
197 REQUIRE(rdata->type == dns_rdatatype_cds);
198 REQUIRE(rdata->length != 0);
202 dns_rdata_toregion(rdata, &sr);
203 return (mem_tobuffer(target, sr.base, sr.length));
207 compare_cds(ARGS_COMPARE) {
211 REQUIRE(rdata1->type == rdata2->type);
212 REQUIRE(rdata1->rdclass == rdata2->rdclass);
213 REQUIRE(rdata1->type == dns_rdatatype_cds);
214 REQUIRE(rdata1->length != 0);
215 REQUIRE(rdata2->length != 0);
217 dns_rdata_toregion(rdata1, &r1);
218 dns_rdata_toregion(rdata2, &r2);
219 return (isc_region_compare(&r1, &r2));
222 static inline isc_result_t
223 fromstruct_cds(ARGS_FROMSTRUCT) {
224 dns_rdata_cds_t *ds = source;
226 REQUIRE(type == dns_rdatatype_cds);
227 REQUIRE(source != NULL);
228 REQUIRE(ds->common.rdtype == type);
229 REQUIRE(ds->common.rdclass == rdclass);
230 switch (ds->digest_type) {
231 case DNS_DSDIGEST_SHA1:
232 REQUIRE(ds->length == ISC_SHA1_DIGESTLENGTH);
234 case DNS_DSDIGEST_SHA256:
235 REQUIRE(ds->length == ISC_SHA256_DIGESTLENGTH);
237 case DNS_DSDIGEST_GOST:
238 REQUIRE(ds->length == ISC_GOST_DIGESTLENGTH);
240 case DNS_DSDIGEST_SHA384:
241 REQUIRE(ds->length == ISC_SHA384_DIGESTLENGTH);
248 RETERR(uint16_tobuffer(ds->key_tag, target));
249 RETERR(uint8_tobuffer(ds->algorithm, target));
250 RETERR(uint8_tobuffer(ds->digest_type, target));
252 return (mem_tobuffer(target, ds->digest, ds->length));
255 static inline isc_result_t
256 tostruct_cds(ARGS_TOSTRUCT) {
257 dns_rdata_cds_t *ds = target;
260 REQUIRE(rdata->type == dns_rdatatype_cds);
261 REQUIRE(target != NULL);
262 REQUIRE(rdata->length != 0);
264 ds->common.rdclass = rdata->rdclass;
265 ds->common.rdtype = rdata->type;
266 ISC_LINK_INIT(&ds->common, link);
268 dns_rdata_toregion(rdata, ®ion);
270 ds->key_tag = uint16_fromregion(®ion);
271 isc_region_consume(®ion, 2);
272 ds->algorithm = uint8_fromregion(®ion);
273 isc_region_consume(®ion, 1);
274 ds->digest_type = uint8_fromregion(®ion);
275 isc_region_consume(®ion, 1);
276 ds->length = region.length;
278 ds->digest = mem_maybedup(mctx, region.base, region.length);
279 if (ds->digest == NULL)
280 return (ISC_R_NOMEMORY);
283 return (ISC_R_SUCCESS);
287 freestruct_cds(ARGS_FREESTRUCT) {
288 dns_rdata_cds_t *ds = source;
291 REQUIRE(ds->common.rdtype == dns_rdatatype_cds);
293 if (ds->mctx == NULL)
296 if (ds->digest != NULL)
297 isc_mem_free(ds->mctx, ds->digest);
301 static inline isc_result_t
302 additionaldata_cds(ARGS_ADDLDATA) {
303 REQUIRE(rdata->type == dns_rdatatype_cds);
309 return (ISC_R_SUCCESS);
312 static inline isc_result_t
313 digest_cds(ARGS_DIGEST) {
316 REQUIRE(rdata->type == dns_rdatatype_cds);
318 dns_rdata_toregion(rdata, &r);
320 return ((digest)(arg, &r));
323 static inline isc_boolean_t
324 checkowner_cds(ARGS_CHECKOWNER) {
326 REQUIRE(type == dns_rdatatype_cds);
336 static inline isc_boolean_t
337 checknames_cds(ARGS_CHECKNAMES) {
339 REQUIRE(rdata->type == dns_rdatatype_cds);
349 casecompare_cds(ARGS_COMPARE) {
350 return (compare_cds(rdata1, rdata2));
353 #endif /* RDATA_GENERIC_CDS_59_C */